package com.sea.supply.service.impl;

import com.codecrane.core.power.entity.DictDetail;
import com.codecrane.core.power.service.DictDetailService;
import com.codecrane.core.web.BatchImportUtils;
import com.sea.physical.entity.CreateDespatchPlan;
import com.sea.physical.entity.CreatePlan;
import com.sea.physical.service.CreateDespatchPlanService;
import com.sea.physical.service.CreatePlanService;
import com.sea.product.entity.Channel;
import com.sea.product.entity.Product;
import com.sea.supply.entity.*;
import com.sea.supply.mapper.ProduceDetailMapper;
import com.sea.supply.mapper.ReceiveMapper;
import com.sea.supply.service.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.List;


@Service
public class ReceiveServiceImpl implements ReceiveService {

    @Autowired
    private ReceiveMapper receiveMapper;
    @Autowired
    private ProduceDetailMapper produceDetailMapper;
    @Autowired
    private ProduceService produceService;
    @Autowired
    private DictDetailService dictDetailService;
    @Autowired
    private CreatePlanService createPlanService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private WareDistributeService wareDistributeService;
    @Autowired
    private WareReceiveService wareReceiveService;
    @Autowired
    private CreateDespatchPlanService createDespatchPlanService;

    @Override
    public int save(Receive receive) {
        return receiveMapper.insert(receive);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importSku(InputStream inputStream, String fileName, String userRealName) throws Exception {
        Workbook workBook = BatchImportUtils.getWorkBook(inputStream, fileName);
        List<Sheet> sheets = BatchImportUtils.getSheets(workBook);
        if (null != sheets && sheets.size() > 0) {
            Sheet sheet = sheets.get(0);
            List<Receive> list = BatchImportUtils.iteratorForReceive(sheet);
            if (null == list || list.size() == 0) {
                throw new Exception("请至少保存一条SKU收货信息！");
            } else {
                //超收比例
                String receivePercent = dictDetailService.findByTypeCode(26, "1");
                if (StringUtils.isEmpty(receivePercent)) {
                    throw new RuntimeException("无法查询到超售比例！");
                }
                double percent = Double.parseDouble(receivePercent);
                Integer produceId = 0;
                CreateDespatchPlan plan=new CreateDespatchPlan();
                for (Receive receive : list) {
                    plan.setCreateSku(receive.getReceiveSku());
                    plan.setCreatePlanNo(receive.getReceivePlanNo());
                    List<CreateDespatchPlan> pList = createDespatchPlanService.findByCnd(plan);
                    if(null==pList || pList.size()==0) {
                        throw new RuntimeException("暂未查询到SKU信息！【" + receive.getReceiveSku() + "】");
                    }
                    Supplier supplier = supplierService.findBySupplierName(receive.getReceiveWare());
                    if(null==supplier){
                        throw new RuntimeException("暂未查询到供应商信息！【"+receive.getReceiveWare()+"】");
                    }

                    if(supplier.getSupplierWare().equals("否")) {
                        receive(receive, produceId, userRealName, percent);
                    }else{
                        wareReceive(receive,userRealName, produceId);
                    }
                }
            }
        }
    }

    @Override
    public List<Receive> findByCnd(Receive receive) {
        return receiveMapper.findByCnd(receive);
    }

    @Override
    public List<Receive> findByShipped(Receive receive) {
        return receiveMapper.findByShipped(receive);
    }

    @Override
    public Integer getDistributeNumber(String orderSku, String orderChannelName,String orderDate,String producePo) {
        return receiveMapper.getDistributeNumber(orderSku,orderChannelName,orderDate,producePo);
    }

    @Override
    public List<Receive> findByDistributeReadyUse(String orderSku, String orderChannelName,String orderDate,String supplierName,String produceNo) {
        return receiveMapper.findByDistributeReadyUse(orderSku, orderChannelName,orderDate,supplierName,produceNo);
    }

    @Override
    public Receive findByWareProduce(String receiveSku, String receiveChannelName, String produceNo) {
        return receiveMapper.findByWareProduce(receiveSku, receiveChannelName, produceNo);
    }

    @Override
    public List<Receive> findReceivePlanNo() {
        return receiveMapper.findReceivePlanNo();
    }

    @Override
    public Receive findByWareProducePrice(String receiveSku, String receiveChannelName, String produceNo) {
        return receiveMapper.findByWareProduce(receiveSku, receiveChannelName, produceNo);
    }


    //海外仓收货
    @Override
    public void wareReceive(Receive receive,String userRealName,Integer produceId) {
        WareDistribute wareDistribute=new WareDistribute();
        wareDistribute.setProduceNo(receive.getReceiveNo());
        wareDistribute.setReceiveSku(receive.getReceiveSku());
        wareDistribute.setReceiveChannelName(receive.getReceiveChannelName());
        wareDistribute.setWareName(receive.getReceiveWare());
        WareDistribute ware = wareDistributeService.findBySkuChannelNo(wareDistribute);
        if(null==ware){
            throw new RuntimeException("暂未查询到明细信息!【SKU:" + receive.getReceiveSku() + ";渠道:" + receive.getReceiveChannelName() + ";PO:" + receive.getReceiveNo() + "】");
        }else{
            //判断占用量
            Integer produceUse = ware.getProduceUse();
            Integer receiveNumber = receive.getReceiveNumber();
            if(produceUse-receiveNumber<0){
                throw new RuntimeException("占有量异常!【SKU:" + receive.getReceiveSku() + ";渠道:" + receive.getReceiveChannelName() + ";PO:" + receive.getReceiveNo() + "】");
            }
            //释放占有量
            ware.setProduceUse(produceUse-receiveNumber);
            ware.setReceiveNumber(ware.getReceiveNumber()-receiveNumber);
            wareDistributeService.usave(ware);
            //新增收货记录
            WareReceive wareReceive =new WareReceive();
            wareReceive.setProduceDetailId(ware.getId());
            wareReceive.setReceiveMember(userRealName);
            wareReceive.setReceiveNo(receive.getReceiveNo());
            wareReceive.setReceiveChannelName(receive.getReceiveChannelName());
            wareReceive.setReceiveSku(receive.getReceiveSku());
            wareReceive.setReceiveDate(receive.getReceiveDate());
            wareReceive.setReceivePlanNo(receive.getReceivePlanNo());
            wareReceive.setReceiveNumber(receiveNumber);
            wareReceiveService.save(wareReceive);


        }

    }

    @Override
    public List<Receive> findByPlanNo(String receivePlanNo) {
        return receiveMapper.findByPlanNo(receivePlanNo);
    }


    //国内仓收货
    @Override
    public void receive(Receive receive,Integer produceId,String userRealName,double percent){
        String receiveSku = receive.getReceiveSku();
        String receiveNo = receive.getReceiveNo();
        Integer receiveNumber = receive.getReceiveNumber();
        String receiveChannelName = receive.getReceiveChannelName();

        //判断柜号是否为空
        String receivePlanNo = receive.getReceivePlanNo();
        if (StringUtils.isEmpty(receivePlanNo)) {
            throw new RuntimeException("请上传柜号！");
        } else {
            CreatePlan createNo = createPlanService.findByCreateNo(receivePlanNo);
            if (null == createNo) {
                throw new RuntimeException("暂未查询到柜号【" + receivePlanNo + "】");
            }
            Integer createPlanStatus = createNo.getCreatePlanStatus();
            if (createPlanStatus < 3) {
                throw new RuntimeException("请先做发运柜号【" + receivePlanNo + "】");
            }
            ProduceDetail produceDetail = produceDetailMapper.getIdByCnd(receiveSku, receiveChannelName, receive.getOrderDate(), receiveNo);
            if (null == produceDetail) {
                throw new RuntimeException("暂未查询到明细信息!【SKU:" + receiveSku + ";渠道:" + receiveChannelName + ";PO:" + receiveNo + "】");
            }
            // 更新占有量getIdByCnd
            int useNumber = produceDetail.getProduceUse() - receiveNumber;
            if (useNumber < 0) {
                throw new RuntimeException("占有量异常,请检查!【SKU:" + receiveSku + ";渠道:" + receiveChannelName + ";PO:" + receiveNo + "】");
            }
            if(receiveNumber>0){
                produceDetailMapper.updateUseNumber(produceDetail.getProduceUse() - receiveNumber, produceDetail.getId());
            }
        }

        //可收货结果集
        List<ProduceDetail> receiveList = produceDetailMapper.findReceiveNumber(receiveNo, receiveSku, receiveChannelName,receive.getOrderDate());
        if (null == receiveList || receiveList.size() == 0) {
            throw new RuntimeException("无法查询到数据:【" + receiveNo + "-" + receiveSku + "-" + receiveChannelName + "】");
        } else {
            //计算数据
            Integer number = receiveNumber;
            for (int i = 0; i < receiveList.size(); i++) {
                ProduceDetail detail = receiveList.get(i);
                produceId = detail.getProduceId();
                receive.setProduceDetailId(detail.getId());
                receive.setReceiveMember(userRealName);
                //如果是一条则直接判断是否够不够
                if (receiveList.size() == 1) {
                    Integer produceSurplus = detail.getProduceSurplus();
                    //刚好收完
                    if (produceSurplus - receiveNumber == 0 || produceSurplus - receiveNumber > 0) {
                        receive.setReceiveNumber(receiveNumber);
                        save(receive);
                        //更新剩余量
                        detail.setProduceSurplus(produceSurplus - receiveNumber);
                        produceDetailMapper.update(detail);
                        //更新表头信息
                        produceService.updateProduceTotal(detail.getProduceId());

                    } else {
                        Integer produceTotal = detail.getProduceTotal();
                        double v = produceTotal + produceTotal * (percent / 100);
                        Integer total = produceTotal - (produceSurplus - receiveNumber);
                        if (total > v) {
                            throw new RuntimeException("不能超过采购比例" + percent + "%:【" + receiveNo + "-" + receiveSku + "】");
                        } else {
                            receive.setReceiveNumber(receiveNumber);
                            save(receive);
                            //更新剩余量
                            detail.setProduceSurplus(produceSurplus - receiveNumber);
                            produceDetailMapper.update(detail);
                            //更新表头信息
                            produceService.updateProduceTotal(detail.getProduceId());
                        }
                    }
                } else {
                    //如果是多条
                    Integer produceSurplus = detail.getProduceSurplus();
                    //刚好收完
                    if (produceSurplus - number == 0 || produceSurplus - number > 0) {
                        receive.setReceiveNumber(number);
                        save(receive);
                        //更新剩余量
                        detail.setProduceSurplus(produceSurplus - number);
                        produceDetailMapper.update(detail);
                        //更新表头信息
                        produceService.updateProduceTotal(detail.getProduceId());
                        break;
                    } else {
                        if (i != receiveList.size() - 1 && (produceSurplus - number == 0 || produceSurplus - number > 0)) {
                            receive.setReceiveNumber(number);
                            save(receive);
                            //更新剩余量
                            detail.setProduceSurplus(produceSurplus - number);
                            produceDetailMapper.update(detail);
                            //更新表头信息
                            produceService.updateProduceTotal(detail.getProduceId());
                            break;
                        } else if (i != receiveList.size() - 1 && (produceSurplus - number < 0)) {
                            number = number - produceSurplus;
                            receive.setReceiveNumber(produceSurplus);
                            save(receive);
                            detail.setProduceSurplus(0);
                            produceDetailMapper.update(detail);
                            //更新表头信息
                            produceService.updateProduceTotal(detail.getProduceId());
                        }
                        //如果是最后一条数量够
                        if (i == receiveList.size() - 1 && (produceSurplus - number == 0 || produceSurplus - number > 0)) {
                            receive.setReceiveNumber(number);
                            save(receive);
                            //更新剩余量
                            detail.setProduceSurplus(produceSurplus - number);
                            produceDetailMapper.update(detail);
                            //更新表头信息
                            produceService.updateProduceTotal(detail.getProduceId());
                            break;
                        }
                        //如果是最后一条数量不够
                        if (i == receiveList.size() - 1 && number > 0) {
                            Integer produceTotal = detail.getProduceTotal();
                            double v = produceTotal + produceTotal * (percent / 100);
                            Integer total = produceTotal - (produceSurplus - number);
                            if (total > v) {
                                throw new RuntimeException("不能超过采购比例" + percent + "%:【" + receiveNo + "-" + receiveSku + "】");
                            } else {
                                receive.setReceiveNumber(total);
                                save(receive);
                                //更新剩余量
                                detail.setProduceSurplus(produceSurplus - number);
                                produceDetailMapper.update(detail);
                                //更新表头信息
                                produceService.updateProduceTotal(detail.getProduceId());
                            }
                        }
                    }
                }
            }
            Produce pro = produceService.findById(produceId);
            //查询可收获数量
            Integer res = pro.getProduceTotal() - pro.getProduceSurplus();
            if (res > 0 || res<0) {
                //部分收货
                pro.setProduceStatus(31);
                pro.setFlag(null);
                produceService.usave(pro);
            }
            if (res == 0) {
                //全部收货
                pro.setProduceStatus(32);
                pro.setFlag(null);
                produceService.usave(pro);
            }
        }

    }

}
